﻿namespace WPCloudAppIteration2.Phone.ViewModel
{
    using System;
    using System.Globalization;
    using System.Linq;
    using System.Windows;
    using System.Windows.Threading;
    using Microsoft.Phone.Shell;
    using Microsoft.Samples.WindowsPhoneCloud.StorageClient;

    internal enum TableAction
    {
        None = 0,
        Create = 1,
        Delete = 2
    }

    public class TablesPageViewModel : TableBaseViewModel<TableServiceSchema>
    {
        private const string IconsRootUri = "/Toolkit.Content/";

        private TableAction action = TableAction.None;
        private TableServiceSchema currentTable = null;

        public TablesPageViewModel()
            : this(App.CloudClientFactory, Deployment.Current.Dispatcher)
        {
        }

        public TablesPageViewModel(ICloudClientFactory cloudClientFactory, Dispatcher dispatcher)
            : base(cloudClientFactory, dispatcher)
        {
        }

        public override string TableName
        {
            get { return "Tables"; }
        }

        public void NewTable()
        {
            var newTableName = string.Format(CultureInfo.InvariantCulture, "Table{0}", DateTime.Now.ToString("yyyyMMddTHHmmss", CultureInfo.InvariantCulture));
            this.currentTable = new TableServiceSchema(newTableName);
            this.action = TableAction.Create;

            this.Message = "Creating new table...";
            this.IsLoading = true;

            try
            {
                this.Context.AddTable(this.currentTable);
                this.Context.BeginSaveChanges(this.OnBeginSaveChanges, null);
            }
            catch (Exception exception)
            {
                var errorMessage = StorageClientExceptionParser.ParseDataServiceException(exception).Message;

                this.IsLoading = false;
                this.Message = string.Format(CultureInfo.InvariantCulture, "Error: {0}", errorMessage);
            }
        }

        public void DeleteTable(TableServiceSchema table)
        {
            this.currentTable = table;
            this.action = TableAction.Delete;

            this.Message = "Deleting table...";
            this.IsLoading = true;

            try
            {
                // In the case the table was previously detached in a failed operation.
                if (!this.Context.Entities.Any(e => e.Entity == this.currentTable))
                {
                    this.Context.AttachTo("Tables", this.currentTable);
                }

                this.Context.DeleteObject(this.currentTable);
                this.Context.BeginSaveChanges(this.OnBeginSaveChanges, null);
            }
            catch (Exception exception)
            {
                var errorMessage = StorageClientExceptionParser.ParseDataServiceException(exception).Message;

                this.IsLoading = false;
                this.Message = string.Format(CultureInfo.InvariantCulture, "Error: {0}", errorMessage);
            }
        }

        public void OnBeginSaveChanges(IAsyncResult asyncResult)
        {
            this.Dispatcher.BeginInvoke(
                () =>
                {
                    try
                    {
                        this.Context.EndSaveChanges(asyncResult);

                        // Update the Table collection that is binded in the page.
                        if (this.action == TableAction.Create)
                        {
                            this.Table.Add(this.currentTable);
                        }
                        else if (this.action == TableAction.Delete)
                        {
                            this.Table.Remove(this.currentTable);
                        }

                        this.Message = "Changes saved successfully.";
                    }
                    catch (Exception exception)
                    {
                        this.Message = string.Format(
                            CultureInfo.InvariantCulture,
                            "Error: {0}",
                            StorageClientExceptionParser.ParseDataServiceException(exception).Message);

                        // Detach from the Context the table that produced the failed operation.
                        this.Context.Detach(this.currentTable);
                    }
                    finally
                    {
                        this.IsLoading = false;
                    }
                });
        }

        protected override void PopulateApplicationBarButtons(IApplicationBar applicationBar)
        {
            var refreshButton = new ApplicationBarIconButton(new Uri(string.Format(CultureInfo.InvariantCulture, "{0}{1}", IconsRootUri, "appbar.refresh.rest.png"), UriKind.Relative)) { Text = "refresh" };
            refreshButton.Click += (s, e) => this.LoadTable();

            var addButton = new ApplicationBarIconButton(new Uri(string.Format(CultureInfo.InvariantCulture, "{0}{1}", IconsRootUri, "appbar.add.rest.png"), UriKind.Relative)) { Text = "add table" };
            addButton.Click += (s, e) => this.NewTable();

            applicationBar.Buttons.Add(refreshButton);
            applicationBar.Buttons.Add(addButton);
        }
    }
}
